package com.su02.multi.examples.mlp;

import com.su02.multi.chainrule.Constant;
import com.su02.multi.chainrule.Function;

import lombok.Getter;

import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Layer4MLP {
    private final List<Neuron4MLP> neurons = new ArrayList<>();

    @Getter
    private int inSize;

    @Getter
    private int outSize;

    private Layer4MLP() {}

    public List<Double> out(Map<Integer, Double> vector) {
        return out().stream().map(f -> f.forward(vector)).toList();
    }

    public List<Neuron4MLP> out() {
        return Collections.unmodifiableList(neurons);
    }

    public static Layer4MLP fromVector(List<Double> x, int outSize, Iterator<Integer> idGenerator) {
        return fromFunctions(x.stream().map(Constant::new).toList(), outSize, idGenerator);
    }

    public static Layer4MLP fromFunctions(List<? extends Function> fs, int outSize, Iterator<Integer> idGenerator) {
        Layer4MLP ans = new Layer4MLP();
        ans.inSize = CollectionUtils.size(fs);
        ans.outSize = outSize;
        for (int i = 0; i < outSize; i++) {
            Neuron4MLP neuron = Neuron4MLP.fromFunctions(fs, idGenerator);
            ans.neurons.add(neuron);
        }
        return ans;
    }
}